package net.zoneland.knowledge.service;

import com.google.common.collect.Lists;
import net.zoneland.knowledge.enums.AttachTypeEnum;
import net.zoneland.knowledge.exceptions.WorkApplyException;
import net.zoneland.knowledge.model.LoginUserPojo;
import net.zoneland.knowledge.model.WorkApplyInfo;
import net.zoneland.knowledge.model.WorkApplyInfoAttachment;
import net.zoneland.knowledge.model.WorkSubTaskInfo;
import org.apache.commons.collections.CollectionUtils;
import org.joda.time.DateTime;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 附件处理的服务接口。
 * <p>所有附件的处理统一在此提供公共服务</p>
 */
public interface AttachmentService {

    /**
     * 参考文件的参数名.
     */
    public static final String REFERENCE_FILE_NAME = "file";
    /**
     * 模板文件的参数名.
     */
    public static final String TEMPLATE_FILE_NAME = "fileTemplate";
    /**
     * 结果文件的参数名.
     */
    public static final String RESULT_FILE_NAME = "fileRes";

    /**
     * 构造工单附件信息.
     * @param request http请求
     * @param info 工单信息
     * @param user 当前用户
     * @return 工单信息
     */
    void initWorkApplyInfoAttachments(final HttpServletRequest request, final WorkApplyInfo info, final LoginUserPojo user);
    /**
     * 处理参考附件对象集合.
     * @param info 工单信息
     * @param multipartReq 多文件对象
     * @param user 用户对象
     * @return 附件对象集合
     */
    void handleReferenceAttachments(WorkApplyInfo info, LoginUserPojo user, MultipartHttpServletRequest multipartReq);

    /**
     * 处理模板附件对象集合.
     * @param info 工单信息
     * @param multipartReq 多文件对象
     * @param user 用户对象
     * @return 附件对象集合
     */
    void handleTemplateAttachments(WorkApplyInfo info, LoginUserPojo user, MultipartHttpServletRequest multipartReq);

    /**
     * 处理上报附件对象集合.
     * @param info 工单信息
     * @param multipartReq 多文件对象
     * @param user 用户对象
     * @return 附件对象集合
     */
    void handleReportAttachments(List<WorkSubTaskInfo> subTasks, LoginUserPojo user, MultipartHttpServletRequest multipartReq);

    /**
     * 插入分任务附件。
     * @param workSubTaskInfo 分任务
     */
    public void insertAttachmentForSubTask(WorkSubTaskInfo workSubTaskInfo);

    /**
     * 插入模板附件。
     * @param workSubTaskInfo 分任务
     */
    public void insertTemplateAttachment(WorkSubTaskInfo workSubTaskInfo);

    /**
     * 插入上报附件.
     *
     * @param workSubTaskInfo 分任务
     */
    void insertReportAttachment(WorkSubTaskInfo workSubTaskInfo);
    /**
     * 插入合并附件.
     *
     * @param workSubTaskInfo 分任务
     */
    void insertMergeAttachment(WorkSubTaskInfo workSubTaskInfo);
    /**
     * 根据id查询附件信息.
     * @param attachmentId 附件主键id
     * @return 附件对象
     */
    WorkApplyInfoAttachment findWorkAttachmentById(String attachmentId);

    /**
     * 删除附件。
     * @param id 附件id
     */
    void deleteAttachmentById(String id);

    /**
     * 工单级的合并结果附件操作。
     * <p>将子工单的结果附件（也叫上报附件）合并到父工单的合并附件</p>
     * <p>对子工单而言，是整体合并，也即子工单的所有分任务的都要合并到父工单的分任务里</p>
     * <p>合并好的合并附件挂载到父工单对象里，不需要返回</p>
     * @param info 父工单
     * @param needFinishSubApplyList 需要合并的子工单列表
     */
    void mergeResultAttachmentContentForWorkApply(WorkApplyInfo info, List<WorkApplyInfo> needFinishSubApplyList);

    /**
     * 分任务级的合并结果附件操作。
     * <p>将分任务的结果附件（也叫上报附件）合并到父级分任务的合并附件</p>
     * <p>合并好的合并附件挂载到父级分任务对象里，不需要返回</p>
     * @param parentSubTaskInfo 父级分任务
     * @param confirmedSubTaskList 已经被确认的分任务，也即需要合并的下级分任务
     */
    void mergeResultAttachmentContentForSubTask(WorkSubTaskInfo parentSubTaskInfo, List<WorkSubTaskInfo> confirmedSubTaskList);
}
